import ctypes

from StructType import *


class MultiUSVModel(object):
    def __init__(self, dll_path="./dll/usvmodel.dll", dll_deps=[r"./dll/Qt5Core.dll"]):
        _ = [ctypes.CDLL(i) for i in dll_deps]
        self.dll = ctypes.CDLL(dll_path)

        self.dll.cmultiUSVModel_new.argtypes = []
        self.dll.cmultiUSVModel_new.restype = ctypes.c_void_p

        self.dll.cmultiUSVModel_multiInitialize.argtypes = [
            ctypes.c_void_p,
            ctypes.c_int,
        ]
        self.dll.cmultiUSVModel_multiInitialize.restype = None

        self.dll.cmultiUSVModel_updateMultiUSVControl.argtypes = [
            ctypes.c_void_p,
            ctypes.POINTER(USVInitStructType),
            ctypes.c_int,
            ctypes.c_double,
            ctypes.c_int,
        ]
        self.dll.cmultiUSVModel_updateMultiUSVControl.restype = None

        self.dll.cmultiUSVModel_getMultiNaviObsInfo.argtypes = [
            ctypes.c_void_p,
            ctypes.c_int,
            ctypes.POINTER(ctypes.POINTER(USVOutPutStructType)),
            ctypes.POINTER(ctypes.c_int),
            ctypes.POINTER(ctypes.POINTER(InputOBSStruct)),
            ctypes.POINTER(ctypes.c_int),
        ]
        self.dll.cmultiUSVModel_getMultiNaviObsInfo.restype = None

        self.dll.cmultiUSVModel_getTaskInfo.argtypes = [
            ctypes.c_void_p,
            ctypes.POINTER(ctypes.c_int),
            ctypes.POINTER(ctypes.POINTER(SFormationTaskInfo)),
            ctypes.POINTER(ctypes.c_int),
            ctypes.POINTER(ctypes.POINTER(referUSVInfo)),
            ctypes.POINTER(ctypes.c_int),
            ctypes.c_int,
        ]
        self.dll.cmultiUSVModel_getTaskInfo.restype = ctypes.c_int

        self.dll.cmultiUSVModel_taskEnd.argtypes = [
            ctypes.c_void_p,
            ctypes.c_int,
            ctypes.c_int,
        ]
        self.dll.cmultiUSVModel_taskEnd.restype = None
        self.cmultiusvmodel = self.dll.cmultiUSVModel_new()

    def __del__(self):
        ctypes.windll.kernel32.FreeLibrary(ctypes.c_void_p(self.dll._handle))
        self.taskEnd(0, 0)

    def multiInitialize(self, flagModel):
        return self.dll.cmultiUSVModel_multiInitialize(self.cmultiusvmodel, flagModel)

    def updateMultiUSVControl(
        self, multiUSVInitInfo_data, multiUSVInitInfo_size, curTime, flagModel
    ):
        return self.dll.cmultiUSVModel_updateMultiUSVControl(
            self.cmultiusvmodel,
            multiUSVInitInfo_data,
            multiUSVInitInfo_size,
            curTime,
            flagModel,
        )

    def getMultiNaviObsInfo(
        self,
        iterNum,
        multiUSVStatus_data,
        multiUSVStatus_size,
        curOBSFusion_data,
        curOBSFusion_size,
    ):
        return self.dll.cmultiUSVModel_getMultiNaviObsInfo(
            self.cmultiusvmodel,
            iterNum,
            multiUSVStatus_data,
            multiUSVStatus_size,
            curOBSFusion_data,
            curOBSFusion_size,
        )

    def getTaskInfo(
        self,
        isEnd_int,
        taskPath_data,
        taskPath_size,
        referInfo_data,
        referInfo_size,
        iterNum,
    ):
        return self.dll.cmultiUSVModel_getTaskInfo(
            self.cmultiusvmodel,
            isEnd_int,
            taskPath_data,
            taskPath_size,
            referInfo_data,
            referInfo_size,
            iterNum,
        )

    def taskEnd(self, iterNum, modelFlag):
        return self.dll.cmultiUSVModel_taskEnd(self.cmultiusvmodel, iterNum, modelFlag)
